
function game2048(){
    let len = 4 //格子数量
    
    // let size = 100 //格子大小
    // let margin = 20 //格子间隔
    //移动端设置
    let size = 20 //格子大小
    let margin = 4 //格子间隔

    let score = 0 //游戏总分
    let winNum = 32 //获胜分数
    let isGameOver = false //结束标记
    
    let view = new View(len,size,margin)
    let board = new Board(len)

    view.init()
    board.init()


    board.onGenerate = function(e){
        console.log(e);
        view.addNum(e.x,e.y,e.num)
    }

    board.onMove = function(e){
        view.move(e.form,e.to)
        console.log(e.to.num,e.form.num);
        if(e.to.num > e.form.num){
            //合并加分
            score += e.to.num
            view.updateScore(score)
        }
        if(e.to.num >= winNum){
            // alert('恭喜，你获胜了')
            isGameOver = true
            view.win()
        }
    }

    board.onMoveComplete = function(e,arr) {
        if (e.moved) {
            setTimeout(function(){ 
                board.generate(); 
            }, 500);
            setTimeout(function(){
                 view.updateView(arr);
            }, 300)
        }
        if(!board.canMove()){
            isGameOver = true
            // alert('您本次得分为：'+score)
            view.over(score)
        }
    };

    board.generate()
    

    //键盘操作
    $(document).keydown(function(e){
        if(isGameOver){
            return false
        } else {
            switch (e.which) {
                case 37: board.moveLeft();break;
                case 38: board.moveTop();break;
                case 39: board.moveRight();break;
                case 40: board.moveBottom();break;
            }
        }
        
    })  

    // $('#game_restart').click(function(){
    //     restart()
    // })

    $('#game_restart').on('click',function(){
        restart()
    })

    //重新开始
    function restart(){
        score = 0
        view.updateScore(0)
        isGameOver = false

        $('#game_over').addClass('game-hide')
        $('.game-num').remove()

        view.init()
        board.init()

        board.generate()
    }

    //触控
    let startx,starty,endx,endy
    document.addEventListener('touchstart',function(e){
        startx=e.touches[0].pageX
        starty=e.touches[0].pageY
    })

	document.addEventListener('touchend',function(e){
        endx=e.changedTouches[0].pageX
        endy=e.changedTouches[0].pageY

        let tox = endx-startx
        let toy = endy-starty

        if(Math.abs(tox) > Math.abs(toy)){
            //在x轴上移动
            if(tox > 0){
                board.moveRight()
            } else {
                board.moveLeft()
            }
        } else {
            //在y轴移动
            if (toy > 0) {
                board.moveBottom()
            } else {
                board.moveTop()
            }
        }
    })
}



class View{
    constructor(len,size,margin){
        this.len = len
        this.size = size
        this.margin = margin

        this.cellcon = $('#cell-con')
        this.numcon = $('#num-con')
    }

    
    //初始化棋盘
    init(){
        for(let x = 0;x < this.len;x++){
            for(let y = 0;y < this.len;y++){
                let cell = $('<div>').addClass('game-cell').css({
                    left:this.getPos(y)+'%',
                    top:this.getPos(x)+'%'
                })

                this.cellcon.append(cell)
            }
        }
    }

    //获取棋盘位置
    getPos(n){
        return this.margin + n * (this.size + this.margin)
    }

    //添加数字
    addNum(x,y,n){
        let num = $('<div>').addClass(`game-num game-num-${n}`).css({
            left:this.getPos(y)+'%',
            top:this.getPos(x)+'%'
        }).text(n).attr('id',`cell-${x}-${y}`)
        this.numcon.append(num)
    }

    //移动动画
    move(from,to){
        $(`#cell-${from.x}-${from.y}`).finish().animate({
            left:this.getPos(to.y)+'%',
            top:this.getPos(to.x)+'%'
        }),150
    }

    //更新棋盘
    updateView(arr){
        $('.game-num').remove()
        for(let x=0;x<this.len;x++){
            for(let y=0;y<this.len;y++){
                if(arr[x][y]!=0){
                    this.addNum(x,y,arr[x][y])
                }
            }
        }
    }

    //更新分数
    updateScore(score){
        $('#game_score').text(score)
    }

    //游戏结束页面
    win(){
        $('#game_over').removeClass('game-hide')
        $('#game_over_info p').text('恭喜你获胜了')
    }
    over(score){
        $('#game_over').removeClass('game-hide')
        $('#game_over_info p').text('你本次得分：'+score)
    }
}


//控制游戏数值
class Board{
    constructor(len){
        this.len = len
        this.arr = []
    }

    //初始化数组
    init(){
        for(let x = 0;x < this.len;x++){
            this.arr[x] = []
            for(let y = 0;y < this.len;y++){
                this.arr[x][y] = 0
            }
        }
    }

    //随机位置生成数字
    generate(){
        let empty = []
        //获取空位
        for(let x = 0;x < this.len;x++){
            for(let y = 0;y < this.len;y++){
                if(this.arr[x][y] == 0){
                    empty.push({x:x,y:y})
                }
            }
        }

        for(let i = 0;i<2;i++){
            //随机位置
            let rnd = Math.floor(Math.random()*empty.length)
            let one = empty[rnd]
            //随机数字
            this.arr[one.x][one.y] = Math.random() < 0.5 ? 2 : 4

            this.onGenerate({
                x:one.x,
                y:one.y,
                num:this.arr[one.x][one.y]
            });
        }
    }

    //向左移
    moveLeft(){
        let isMoved = false;
        for(let x = 0;x < this.len;x++){
            for(let y = 0;y < this.len;y++){
                for(let next = y + 1;next < this.len;next++){
                    //跳过0
                    if(this.arr[x][next] == 0){
                        continue
                    } else {
                        //交换位置
                        if(this.arr[x][y] == 0){
                            this.arr[x][y] = this.arr[x][next]
                            this.onMove({
                                form:{x:x,y:next,num:this.arr[x][next]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[x][next] = 0
                            isMoved = true
                            y--
                        //有重复数字相加
                        } else if(this.arr[x][y] == this.arr[x][next]){
                            this.arr[x][y] += this.arr[x][next]
                            this.onMove({
                                form:{x:x,y:next,num:this.arr[x][next]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[x][next] = 0
                            isMoved = true
                        }
                    }
                    break  //防止多次相加
                }
            }
        }
        this.onMoveComplete({moved: isMoved},this.arr);
    }

    //向右移
    moveRight(){
        let isMoved = false;
        for(let x = 0;x < this.len;x++){
            for(let y = this.len-1;y >= 0;y--){
                for(let next = y - 1;next >= 0;next--){
                    //跳过0
                    if(this.arr[x][next] == 0){
                        continue
                    } else {
                        //交换位置
                        if(this.arr[x][y] == 0){
                            this.arr[x][y] = this.arr[x][next]
                            this.onMove({
                                form:{x:x,y:next,num:this.arr[x][next]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[x][next] = 0
                            isMoved = true
                            y++
                        //有重复数字相加
                        } else if(this.arr[x][y] == this.arr[x][next]){
                            this.arr[x][y] += this.arr[x][next]
                            this.onMove({
                                form:{x:x,y:next,num:this.arr[x][next]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[x][next] = 0
                            isMoved = true
                        }
                    }
                    break  //防止多次相加
                }
            }
        }
        this.onMoveComplete({moved: isMoved},this.arr);
    }

    //向上移
    moveTop(){
        let isMoved = false;
        for(let y = 0;y < this.len;y++){
            for(let x = 0;x < this.len;x++){
                for(let next = x + 1;next < this.len;next++){
                    //跳过0
                    if(this.arr[next][y] == 0){
                        continue
                    } else {
                        //交换位置
                        if(this.arr[x][y] == 0){
                            this.arr[x][y] = this.arr[next][y]
                            this.onMove({
                                form:{x:next,y:y,num:this.arr[next][y]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[next][y] = 0
                            isMoved = true
                            x--
                        //有重复数字相加
                        } else if(this.arr[x][y] == this.arr[next][y]){
                            this.arr[x][y] += this.arr[next][y]
                            this.onMove({
                                form:{x:next,y:y,num:this.arr[next][y]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[next][y] = 0
                            isMoved = true
                        }
                    }
                    break  //防止多次相加
                }
            }
        }
        this.onMoveComplete({moved: isMoved},this.arr);
    }

    //向下移
    moveBottom(){
        let isMoved = false;
        for(let y = 0;y < this.len;y++){
            for(let x = this.len-1;x >= 0;x--){
                for(let next = x - 1;next >= 0;next--){
                    //跳过0
                    if(this.arr[next][y] == 0){
                        continue
                    } else {
                        //交换位置
                        if(this.arr[x][y] == 0){
                            this.arr[x][y] = this.arr[next][y]
                            this.onMove({
                                form:{x:next,y:y,num:this.arr[next][y]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[next][y] = 0
                            isMoved = true
                            x++
                        //有重复数字相加
                        } else if(this.arr[x][y] == this.arr[next][y]){
                            this.arr[x][y] += this.arr[next][y]
                            this.onMove({
                                form:{x:next,y:y,num:this.arr[next][y]},
                                to:{x:x,y:y,num:this.arr[x][y]}
                            })
                            this.arr[next][y] = 0
                            isMoved = true
                        }
                    }
                    break  //防止多次相加
                }
            }
        }
        this.onMoveComplete({moved: isMoved},this.arr);
    }

    //判断是否可以移动
    canMove(){
        for(let x = 0;x < this.len;x++){
            for(let y = 0;y < this.len;y++){
                if(this.arr[x][y] == 0){
                    return true
                }
                let cur = this.arr[x][y]
                let right = this.arr[x][y+1]
                let dowm = this.arr[x+1] ? this.arr[x+1][y] : null
                if(cur == right || cur == dowm){
                    return true
                }
            }
        }
        return false
    }

    onGenerate(){}
    
    onMove(){}

    onMoveComplete(){}
    


}

